{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "cf1244a8",
   "metadata": {},
   "source": [
    "| [01_base/05_集合类型_set.ipynb](https://github.com/shibing624/python-tutorial/blob/master/01_base/05_集合类型_set.ipynb)  | Python集合  |[Open In Colab](https://colab.research.google.com/github/shibing624/python-tutorial/blob/master/01_base/05_集合类型_set.ipynb) |\n",
    "\n",
    "\n",
    "# 集合\n",
    "\n",
    "列表和字符串都是一种有序序列，而集合 set 是一种无序的序列。\n",
    "\n",
    "因为集合是无序的，所以当集合中存在两个同样的元素的时候，只会保存其中的一个（唯一性）；\n",
    "同时为了确保其中不包含同样的元素，集合中放入的元素只能是不可变的对象（确定性）。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b7f713ae",
   "metadata": {},
   "source": [
    "## 创建集合"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "id": "39853c8a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "set()\n",
      "<class 'set'>\n"
     ]
    }
   ],
   "source": [
    "# 可以用set()函数来显示的生成空集合：\n",
    "a = set()\n",
    "print(a)\n",
    "print(type(a))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "id": "0b0af1cb",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{1, 2, 3}"
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 使用一个列表来初始化一个集合：\n",
    "a = set([1, 2, 3, 1])\n",
    "a  # 集合会自动去除重复元素 1。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "id": "c56f8da2",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{1, 2, 3}\n"
     ]
    }
   ],
   "source": [
    "# 集合中的元素是用大括号{}包含起来的，这意味着可以用{}的形式来创建集合：\n",
    "a = {1, 2, 3, 1}\n",
    "print(a)  # {1, 2, 3}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "id": "d28bb50e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'dict'>\n"
     ]
    }
   ],
   "source": [
    "# 但是创建空集合的时候只能用set来创建，因为在Python中{}创建的是一个空的字典：\n",
    "s = {}\n",
    "print(type(s))  # <type 'dict'>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "287f942d",
   "metadata": {},
   "source": [
    "## 集合操作"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "id": "f8657532",
   "metadata": {},
   "outputs": [],
   "source": [
    "a = {1, 2, 3, 4}\n",
    "b = {2, 3, 4, 5}"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "faeb338c",
   "metadata": {},
   "source": [
    "### 并\n",
    "\n",
    "两个集合的并，返回包含两个集合所有元素的集合（去除重复）。\n",
    "可以用方法 a.union(b) 或者操作 a | b 实现。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "id": "192fde11",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{1, 2, 3, 4, 5}\n",
      "{1, 2, 3, 4, 5}\n"
     ]
    }
   ],
   "source": [
    "c = a.union(b)\n",
    "print(c)  # {1, 2, 3, 4, 5, 6}\n",
    "\n",
    "# 操作 a | b 实现\n",
    "d = a | b\n",
    "print(c)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "id": "ff8c6139",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 47,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "c == d"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "832b1ab6",
   "metadata": {},
   "source": [
    "### 交\n",
    "两个集合的交，返回包含两个集合共有元素的集合。\n",
    "\n",
    "可以用方法 a.intersection(b) 或者操作 a & b 实现。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "id": "4226876a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{2, 3, 4}\n",
      "{2, 3, 4}\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "c = a.intersection(b)\n",
    "print(c)  # set([2, 3, 4])\n",
    "\n",
    "d = a & b\n",
    "print(d)\n",
    "\n",
    "c == d"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8ec6059e",
   "metadata": {},
   "source": [
    "### 差\n",
    "a 和 b 的差集，返回只在 a 不在 b 的元素组成的集合。\n",
    "\n",
    "可以用方法 a.difference(b) 或者操作 a - b 实现。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "id": "993870eb",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{1}\n",
      "{1}\n"
     ]
    }
   ],
   "source": [
    "c = a.difference(b)\n",
    "print(c)  # set([1])\n",
    "d = a - b\n",
    "print(d)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0d1ce4ce",
   "metadata": {},
   "source": [
    "### 对称差\n",
    "a 和b 的对称差集，返回在 a 或在 b 中，但是不同时在 a 和 b 中的元素组成的集合。\n",
    "\n",
    "可以用方法 a.symmetric_difference(b) 或者操作 a ^ b 实现（异或操作符）。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "id": "b937bdf6",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{1, 5}\n",
      "{1, 5}\n"
     ]
    }
   ],
   "source": [
    "c = a.symmetric_difference(b)\n",
    "print(c)  # set([1, 5])\n",
    "\n",
    "d = a ^ b\n",
    "print(d)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fb47fd3a",
   "metadata": {},
   "source": [
    "### 包含关系\n",
    "\n",
    "要判断 b 是不是 a 的子集，可以用 b.issubset(a) 方法，\n",
    "或者更简单的用操作 b <= a ："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "id": "be34831c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "a = {1, 2, 3}\n",
    "b = {1, 2}\n",
    "\n",
    "c = b.issubset(a)\n",
    "print(c)  # True\n",
    "\n",
    "d = (b <= a)\n",
    "print(d)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3f268645",
   "metadata": {},
   "source": [
    "也可以用 a.issuperset(b) 或者 a >= b 来判断："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "id": "c2afbe0d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n"
     ]
    }
   ],
   "source": [
    "print(a >= b)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "df54dce0",
   "metadata": {},
   "source": [
    "方法只能用来测试子集，但是操作符可以用来判断真子集："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "id": "4aafbb05",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "False\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "print(a < a)  # False\n",
    "print(a <= a)  # True"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cdf443d9",
   "metadata": {},
   "source": [
    "## 集合方法\n",
    "\n",
    "### add 方法向集合添加单个元素\n",
    "\n",
    "跟列表的 append 方法类似，用来向集合添加单个元素。\n",
    "\n",
    "s.add(a) 将元素 a 加入集合 s 中。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "id": "82d646a8",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{1, 3, 4}\n",
      "{1, 3, 4, 5}\n"
     ]
    }
   ],
   "source": [
    "s = {1, 3, 4}\n",
    "s.add(4)\n",
    "print(s)  # set([1, 3, 4])\n",
    "\n",
    "s.add(5)\n",
    "print(s)  # set([1, 3, 4, 5])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "aed2de2f",
   "metadata": {},
   "source": [
    "### update 方法向集合添加多个元素\n",
    "跟列表的extend方法类似，用来向集合添加多个元素。\n",
    "\n",
    "s.update(seq)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "id": "c0591807",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{1, 3, 4, 5, 10, 11, 12}\n"
     ]
    }
   ],
   "source": [
    "s.update([10, 11, 12])\n",
    "print(s)  # set([1, 3, 4, 5, 10, 11, 12])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "id": "888ae61f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{3, 4}\n"
     ]
    }
   ],
   "source": [
    "# remove 方法移除单个元素\n",
    "s = {1, 3, 4}\n",
    "s.remove(1)\n",
    "print(s)  # set([3, 4])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "016ff684",
   "metadata": {},
   "source": [
    "### pop 方法弹出元素\n",
    "由于集合没有顺序，不能像列表一样按照位置弹出元素，\n",
    "\n",
    "所以 pop 方法删除并返回集合中任意一个元素，如果集合中没有元素会报错。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "id": "8ffbe8b7",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{3, 4} 1\n"
     ]
    }
   ],
   "source": [
    "s = {1, 3, 4}\n",
    "d = s.pop()\n",
    "print(s, d)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "id": "c8353563",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{1, 4}\n"
     ]
    }
   ],
   "source": [
    "# discard 方法作用与 remove 一样\n",
    "s = {1, 3, 4}\n",
    "s.discard(3)\n",
    "print(s)  # set([1, 4])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a8cbabdc",
   "metadata": {},
   "source": [
    "### difference_update方法\n",
    "\n",
    "a.difference_update(b) 从a中去除所有属于b的元素："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "id": "06c93053",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{1}\n"
     ]
    }
   ],
   "source": [
    "a = {1, 2, 3, 4}\n",
    "b = {2, 3, 4, 5}\n",
    "a.difference_update(b)\n",
    "print(a)  # set([1])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "33401a9f",
   "metadata": {},
   "source": [
    "本节完。"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}